package com.yanqu.road.server.gameplayer.module.wineshop;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.skill.SkillUpgradeInfo;
import com.yanqu.road.entity.config.wineshop.WineShopBuilding;
import com.yanqu.road.entity.config.wineshop.WineShopEvent;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogBeautySkillExp;
import com.yanqu.road.entity.log.LogWineShopBuildingUpgrade;
import com.yanqu.road.entity.log.LogWineShopPower;
import com.yanqu.road.entity.log.LogWineShopReward;
import com.yanqu.road.entity.messageSubscribe.entity.MessageUserNoticeData;
import com.yanqu.road.entity.player.UserBeauty;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.servercenter.GameEditLimit;
import com.yanqu.road.entity.task.args.WineShopRankArgs;
import com.yanqu.road.entity.task.args.union.UnionActivityTaskArgs;
import com.yanqu.road.entity.wineshop.*;
import com.yanqu.road.logic.bussiness.player.UserWineShopBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.pb.wineshop.WineShopProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.ColdRoomModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.gameplayer.module.xiaomian.XiaoMianModule;
import com.yanqu.road.server.manger.ForbiddenWordMgr;
import com.yanqu.road.server.manger.GameEditLimitMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.config.*;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.messagesubscribe.MessageSubscribeMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.pb.WineShopPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author ：zfr
 * @date ：2021/6/30 16:20
 * 酒肆
 */
public class WineShopModule extends GeneralModule {
    private static Logger logger = LogManager.getLogger(WineShopModule.class.getName());
    private UserWineShopData userWineShopData; //玩家酒肆数据
    private Map<Integer, UserWineShopBuilding> userWineShopBuildingMap = new ConcurrentHashMap<>(); //buildId - data 酒肆内建筑数据
    private int lastSaveTimePower = -1;					//上线前最后一次保存的用户酒肆体力数据 用于找回
    public WineShopModule(GamePlayer player) {
        super(player);
    }

    public UserWineShopData getUserWineShopData() {
        return userWineShopData;
    }

    public Map<Integer, UserWineShopBuilding> getUserWineShopBuildingMap() {
        return userWineShopBuildingMap;
    }

    @Override
    public boolean loadData() {
        userWineShopData = UserWineShopBusiness.getUserWineShopData(player.getUserId());
        if (userWineShopData == null) {
            initUserWineShopData();
        }
        lastSaveTimePower = userWineShopData.getPower();
        userWineShopBuildingMap = UserWineShopBusiness.getUserWineShopBuildingMap(getUserId());
        return true;
    }

    @Override
    public void afterLogin() {
        syncWineShopData();
    }

    @Override
    public void loginSendMsg() {

    }
    /**
     * 同步酒肆数据
     */
    public void syncWineShopData() {
        //之前队列里有多个美女 会记录是否离开 队列内的美女全部离开 需要移除队列
        //现在队列只有一个美女 美女离开直接移除队列
        List<Long> needRemoveArray = new ArrayList<>();
        for (WineShopBeautyArray array : userWineShopData.getRunningBeautyArrays()) {
            boolean needRemove = true;
            for (WineShopBeauty wineShopBeauty : array.getWineShopBeautyList()) {
                if (!wineShopBeauty.isExit()) {
                    needRemove = false;
                }
            }
            if (needRemove) {
                needRemoveArray.add(array.getArrayId());
            }
        }
        for (Long arrayId : needRemoveArray) {
            for (WineShopBeautyArray runningBeautyArray : userWineShopData.getRunningBeautyArrays()) {
                if (runningBeautyArray.getArrayId() == arrayId) {
                    userWineShopData.getRunningBeautyArrays().remove(runningBeautyArray);
                    break;
                }
            }
        }

        //同步体力恢复
        recoveryEnergy();
        player.sendPacket(ClientProtocol.U_WINESHOP_SYNC_DATA, WineShopPb.parseWineShopData(userWineShopData, userWineShopBuildingMap));
    }

    /**
     * 初始化玩家数据
     */
    private void initUserWineShopData() {
        userWineShopData = new UserWineShopData();
        userWineShopData.setUserId(player.getUserId());
        userWineShopData.setUnlockRegion(1);
        userWineShopData.setWineShopLv(1);
        userWineShopData.setPower(GameConfig.WINESHOP_ENERGY_INIT);
        userWineShopData.setInsertOption();
    }

    /**
     * 酒肆等级提升
     *
     * @return ret
     */
    public int wineShopUpgrade() {
        //等级参数 升级类型|技能效果1|技能效果2
        int upgradeType = Integer.parseInt(GameConfig.WINESHOP_MAIN_BUILDING_LEVEL_CONFIG.split("\\|")[0]);
        int curLv = userWineShopData.getWineShopLv();
        //下一等级的升级参数 获取用来判断 不存在则已经满级
        SkillUpgradeInfo nextSkillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(upgradeType, curLv + 1);
        //当前等级的升级参数
        SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(upgradeType, curLv);
        if (nextSkillUpgradeInfo == null || skillUpgradeInfo == null) {
            return GameErrorCode.E_WINESHOP_BUILDING_LV_LIMIT;
        }
        //知名度不满足(只需要判断是否足够 不需要消耗)
        if (userWineShopData.getPopularityValue() < skillUpgradeInfo.getConsumeCount()) {
            return GameErrorCode.E_WINESHOP_POPULARITY_LIMIT;
        }
        userWineShopData.setWineShopLv(userWineShopData.getWineShopLv() + 1);
        //酒肆等级提升 影响门客美女经验获得 都是在结算的时候计算的收益 所以不用实时同步
        syncWineShopData();
        return 0;
    }

    /**
     * 建筑解锁
     * @param buildingId 建筑id
     * @return ret
     */
    public int unlockBuilding(int buildingId) {
        //系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.WineShop.getValue())) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        //建筑已解锁
        if (userWineShopBuildingMap.containsKey(buildingId)) {
            return GameErrorCode.E_WINESHOP_BUILDING_IS_UNLOCK;
        }
        WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(buildingId);
        //配置不存在
        if (wineShopBuilding != null) {
            //区域未解锁 必须先解锁对应区域 才能解锁建筑
            if (userWineShopData.getUnlockRegion() < wineShopBuilding.getRegion()) {
                return GameErrorCode.E_WINESHOP_REGION_IS_LOCK;
            }
            //前置建筑未解锁 建筑有前置建筑要求的 需要先解锁前置建筑才能解锁
            if (wineShopBuilding.getPreBuildingId() != 0 && !userWineShopBuildingMap.containsKey(wineShopBuilding.getPreBuildingId())) {
                return GameErrorCode.E_WINESHOP_PREBUILDING_IS_LOCK;
            }
            //知名度不满足
            if (userWineShopData.getPopularityValue() < wineShopBuilding.getUnlock()) {
                return GameErrorCode.E_WINESHOP_POPULARITY_LIMIT;
            }
            //解锁
            UserWineShopBuilding userWineShopBuilding = new UserWineShopBuilding();
            userWineShopBuilding.setUserId(player.getUserId());
            userWineShopBuilding.setId(buildingId);
            userWineShopBuilding.setLv(1);
            userWineShopBuilding.setInsertOption();
            userWineShopBuildingMap.put(buildingId, userWineShopBuilding);
            //解锁建筑提升酒肆知名度
            userWineShopData.setPopularityValue(userWineShopData.getPopularityValue() + wineShopBuilding.getUnlockWellKnown());
            player.notifyListener(eGamePlayerEventType.WineShopPopularityValueAdd.getValue(), wineShopBuilding.getUnlockWellKnown());
            //知名度提升同步知名榜
            changePopularityValueRank();
            //提升容量
            if (wineShopBuilding.getGuest() > 0) {
                //可以装更多人了 推动进程
                syncProcess();
            }
            //酒肆建筑会提升美女亲密度 所以要实时同步美女数据
            syncBeautyList();
            syncWineShopData();
            return 0;
        }
        return GameErrorCode.E_WINESHOP_BUILDING_CONFIG_NO_FOUND;
    }

    /**
     * 同步美女列表
     */
    private void syncBeautyList() {
        BeautyModule beautyModule = player.getModule(BeautyModule.class);
        for (UserBeauty userBeauty : beautyModule.getBeautyMap().values()) {
            player.getModule(SkinModule.class).recaclBeautyAttr(userBeauty, false); //是否需要加入日志
        }
        beautyModule.syncUserBeauty(new ArrayList<>(beautyModule.getBeautyMap().values()), false);
    }
    /**
     * 建筑升级
     *
     * @param buildingId 建筑id
     * @return ret
     */
    public int buildingUpgrade(int buildingId) {
        //建筑未解锁
        UserWineShopBuilding userWineShopBuilding = userWineShopBuildingMap.get(buildingId);
        if (userWineShopBuilding == null) {
            return GameErrorCode.E_WINESHOP_BUILDING_IS_LOCK;
        }
        WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(buildingId);
        //配置不存在
        if (wineShopBuilding != null) {
            int lv = userWineShopBuilding.getLv();
            //当前等级的升级参数
            SkillUpgradeInfo curLv = SkillMgr.getSkillUpgradeInfo(Integer.parseInt(wineShopBuilding.getUpgradeType()), lv);
            //下一等级的升级参数 获取用来判断 不存在则已经满级
            SkillUpgradeInfo nextLv = SkillMgr.getSkillUpgradeInfo(Integer.parseInt(wineShopBuilding.getUpgradeType()), lv + 1);
            //满级了
            if (curLv == null || nextLv == null) {
                return GameErrorCode.E_WINESHOP_BUILDING_LV_LIMIT;
            }
            //消耗 等级配置的消耗参数 * 建筑的升级参数千分比 向下取整
            long consume = BigDecimal.valueOf(curLv.getConsumeCount()).multiply(new BigDecimal(wineShopBuilding.getUpgradePar())).divide(new BigDecimal(1000), 0, BigDecimal.ROUND_DOWN).longValue();
            //道具不足
            Property consumeProperty = new Property(Integer.parseInt(wineShopBuilding.getUpgradeItem()), BigInteger.valueOf(consume));
            if (!player.getModule(CurrencyModule.class).removeCurrency(consumeProperty, eLogMoneyType.WineShop, eLogMoneyType.WineShopBuildingUpgradeConsume)) {
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
            //升级
            userWineShopBuilding.setLv(userWineShopBuilding.getLv() + 1);
            //提升建筑升级知名度
            userWineShopData.setPopularityValue(userWineShopData.getPopularityValue() + wineShopBuilding.getUpgradeWellKnown());
            player.notifyListener(eGamePlayerEventType.WineShopPopularityValueAdd.getValue(), wineShopBuilding.getUnlockWellKnown());
            //同步知名榜
            changePopularityValueRank();
            AutoLogMgr.add(new LogWineShopBuildingUpgrade(getUserId(), buildingId, lv, userWineShopBuilding.getLv(), PropertyHelper.parsePropertyToString(consumeProperty)));
            //酒肆建筑会提升美女亲密度 所以要实时同步美女数据
            syncBeautyList();
            syncWineShopData();
            return 0;
        }
        return GameErrorCode.E_WINESHOP_BUILDING_CONFIG_NO_FOUND;
    }

    /**
     * 建筑升级（同步升级所以建筑1级）
     */
    public int buildingUpgradeOneKey(int region) {

        WineShopProto.WineShopBuildingUpgradeOneKeyRespMsg.Builder clientMsg = WineShopProto.WineShopBuildingUpgradeOneKeyRespMsg.newBuilder();
        clientMsg.setRet(0);

        int wellKnow = 0;

        //计算所有消耗
        Property allCost = new Property();

        Map<Integer, Property> consumeList = new HashMap<>();

        for (Map.Entry<Integer, UserWineShopBuilding> entry : userWineShopBuildingMap.entrySet()) {
            UserWineShopBuilding building = entry.getValue();
            int buildingId = building.getId();
            WineShopBuilding buildingInfo = WineShopMgr.getWineShopBuilding(buildingId);
            if(buildingInfo == null){
                continue;
            }
            if(buildingInfo.getRegion() != region){
                continue;
            }

            SkillUpgradeInfo curLv = SkillMgr.getSkillUpgradeInfo(Integer.parseInt(buildingInfo.getUpgradeType()), building.getLv());
            if(curLv == null){
                continue;
            }

            SkillUpgradeInfo nextLv = SkillMgr.getSkillUpgradeInfo(Integer.parseInt(buildingInfo.getUpgradeType()), building.getLv() + 1);
            if(nextLv == null){
                continue;
            }
            long consume = BigDecimal.valueOf(curLv.getConsumeCount()).multiply(new BigDecimal(buildingInfo.getUpgradePar())).divide(new BigDecimal(1000), 0, BigDecimal.ROUND_DOWN).longValue();
            Property consumeProperty = new Property(Integer.parseInt(buildingInfo.getUpgradeItem()), BigInteger.valueOf(consume));

            allCost.addProperty(consumeProperty);
            consumeList.put(buildingId, consumeProperty);
            wellKnow += buildingInfo.getUpgradeWellKnown();

            WineShopProto.WineShopBuildingUpgradeTemp.Builder tempBuilder = WineShopProto.WineShopBuildingUpgradeTemp.newBuilder();
            tempBuilder.setBuildingId(buildingId);
            tempBuilder.setOldLv(building.getLv());
            tempBuilder.setNewLv(building.getLv() + 1);

            clientMsg.addResult(tempBuilder);
        }

        if(allCost.isNothing()){
            //重要，用于容错
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //道具是否足够
        if (!player.getModule(CurrencyModule.class).removeCurrency(allCost, eLogMoneyType.WineShop, eLogMoneyType.WineShopBuildingUpgradeSyncConsume)) {

            clientMsg.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            player.sendPacket(ClientProtocol.U_WINESHOP_BUILDING_UPGRADE_ONE_KEY, clientMsg);

        }else {

            for (Map.Entry<Integer, Property> entry : consumeList.entrySet()) {
                int buildingId = entry.getKey();
                UserWineShopBuilding building = userWineShopBuildingMap.get(buildingId);
                AutoLogMgr.add(new LogWineShopBuildingUpgrade(getUserId(), buildingId, building.getLv(), building.getLv() + 1, PropertyHelper.parsePropertyToString(entry.getValue())));
                //升级
                building.setLv(building.getLv() + 1);
            }
            //提升建筑升级知名度
            userWineShopData.setPopularityValue(userWineShopData.getPopularityValue() + wellKnow);
            player.notifyListener(eGamePlayerEventType.WineShopPopularityValueAdd.getValue(), wellKnow);

            syncWineShopData();
            player.sendPacket(ClientProtocol.U_WINESHOP_BUILDING_UPGRADE_ONE_KEY, clientMsg);

            //同步知名榜
            changePopularityValueRank();
            //酒肆建筑会提升美女亲密度 所以要实时同步美女数据
            syncBeautyList();
        }
        return 0;
    }

    /**
     * 榜单变更
     */
    public void changePopularityValueRank() {
        try {
            //知名榜 需要展示酒肆招牌 所以带上酒肆招牌名称的参数
            RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(userWineShopData.getPopularityValue()), eRankType.WineShopPopularityValue.getValue(), userWineShopData.getWineShopName());
        } catch (Exception ex) {
            log.error(ex);
        }
    }

    /**
     * 区域解锁
     * 区域解锁需上一区域的所有建筑都解锁
     * @param region 区域
     * @return ret
     */
    public int unlockRegion(int region) {
        //系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.WineShop.getValue())) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        //默认可以解锁的酒肆参数
        String defaultUnlockZoneParam = GameConfig.WINESHOP_DEFAUT_UNLOCK_ZONE;
        String[] split = defaultUnlockZoneParam.split(";");
        List<Integer> defaultUnlockRegionList = new ArrayList<>();
        for (String regionStr : split) {
            defaultUnlockRegionList.add(Integer.parseInt(regionStr));
        }
        List<Integer> regionSort = WineShopMgr.getRegionSort();
        //请求解锁的区域不存在
        if (!regionSort.contains(region)) {
            return GameErrorCode.E_WINESHOP_REGION_NO_FOUND;
        }
        //判断解锁顺序 请求解锁的区域的排序在当前解锁进度之前的 判定为已解锁
        if (regionSort.indexOf(region) <= regionSort.indexOf(userWineShopData.getUnlockRegion())) {
            return GameErrorCode.E_WINESHOP_REGION_IS_UNLOCK;
        }
        //请求解锁的区域是默认可解锁的 就直接解锁
        if (defaultUnlockRegionList.contains(region)) {
            userWineShopData.setUnlockRegion(region);
            syncWineShopData();
            return 0;
        }
        //解锁区域的上一区域建筑全解锁 才可以解锁
        List<WineShopBuilding> lastZoneBuildingList = WineShopMgr.getLastRegionBuildingList(region);
        for (WineShopBuilding wineShopBuilding : lastZoneBuildingList) {
            if (!userWineShopBuildingMap.containsKey(wineShopBuilding.getId())) {
                return GameErrorCode.E_WINESHOP_LAST_ZONE_BUILDING_NO_ALL_UNLOCK;
            }
        }
        userWineShopData.setUnlockRegion(region);
        syncWineShopData();
        return 0;
    }

    /**
     * 体力恢复
     */
    private void recoveryEnergy() {
        int beforePower = userWineShopData.getPower();
        CalcPowerResult calcPowerResult = PowerHelper.calcPower(userWineShopData.getLastRecoverPowerTime() / 1000,
                GameConfig.WINESHOP_ENERGY_RECOVERY_TIME, GameConfig.WINESHOP_ENERGY_RECOVERY_COUNT_ONCE, GameConfig.WINESHOP_ENERGY_LIMIT, beforePower);
        userWineShopData.setPower(calcPowerResult.getCurPower());
        userWineShopData.setLastRecoverPowerTime(calcPowerResult.getLastRecoverTime() * 1000);
        int addCount = userWineShopData.getPower() - beforePower;
        if (addCount > 0) {
            AutoLogMgr.add(new LogWineShopPower(getUserId(), userWineShopData.getPower(), true, addCount, eLogMoneyType.WineShopRecoverPowerGet.getValue()));
        }
    }

    private void travelRecoveryTime(){
        if(!MessageSubscribeMgr.isSwitch()){
            return;
        }
        long nowTime = System.currentTimeMillis();
        long recoveryTime = 0;

        int maxEnergy = GameConfig.WINESHOP_ENERGY_LIMIT;
        long energyRestoreTime = GameConfig.WINESHOP_ENERGY_RECOVERY_TIME * 1000;
        if(userWineShopData.getPower() < maxEnergy){
            recoveryTime = nowTime + energyRestoreTime * (maxEnergy - userWineShopData.getPower());
        }
        MessageUserNoticeData noticeData = MessageSubscribeMgr.getUserNoticeData(player.getUserId());
        noticeData.setWineShopTime(recoveryTime);
    }

    /**
     * 叫号 接待美女
     * @return ret
     */
    public int receptionBeauty() {
        int checkResult = receptionCheck(false);
        if (checkResult != 0) {
            return checkResult;
        }
        //等候区的人数
        int waitNum = calcWaitBeautyNum();
        //招待满了
        if (waitNum + userWineShopData.getWaitGenerateCount() >= GameConfig.WINESHOP_RECEPTION_LIMIT) {
            return GameErrorCode.E_WINESHOP_RECEPTION_NUM_LIMIT;
        }
        long nowTime = System.currentTimeMillis();
        //酒肆如果是空的没有客人 则将上一次招待完成的时间设置为当前(避免招待后触发离线接待瞬间完成)
        if (isWineShopEmpty()) {
            userWineShopData.setLastReceptionBeautyTime(nowTime);
        }
        //把等待生成的客人数量+1 然后推动进程
        userWineShopData.setWaitGenerateCount(userWineShopData.getWaitGenerateCount() + 1);
        //叫号 推动进程
        syncProcess();
        //扣体力
        userWineShopData.setPower(userWineShopData.getPower() - 1);
        //处理酒肆冲榜活动
        addActivityData(1);
        //小面任务进度
        player.getModule(XiaoMianModule.class).addWineShopCallNumber(1);
        player.notifyListener(eGamePlayerEventType.WineShopReception.getValue(),1);
        player.notifyListener(eGamePlayerEventType.UnionWineShopReception.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, 1, player.getUserInfo().getUnionUid()));
        AutoLogMgr.add(new LogWineShopPower(getUserId(), userWineShopData.getPower(), false, 1, eLogMoneyType.WineShopReceptionPowerConsume.getValue()));
        syncWineShopData();

        if (userWineShopData.getPower() <= 0) {
            player.notifyListener(eGamePlayerEventType.RechargeWineShopReceptionCountNew.getValue(), 0);
        }
        try {
            travelRecoveryTime();
        }catch (Exception e){
            log.error("error:" + e);
        }
        return 0;
    }

    /**
     * 没顾客了
     * @return
     */
    private boolean isWineShopEmpty() {
        return  userWineShopData.getRunningBeautyArrays().isEmpty() &&
                userWineShopData.getWaitWineShopBeautyArrays().isEmpty() &&
                userWineShopData.getWaitGenerateCount() == 0;
    }

    /**
     * 检查队列
     * @param time
     * @return
     */
    private boolean generateBeauty(long time) {
        //有可以生成的顾客且等候区没满就可以生成美女
        if ((getCanReceptionBeautyList().size() > 0 || getCanReceptionPatronsList().size() > 0) && calcWaitBeautyNum() < calcWaitBeautyLimitCount()) {
            //判断双人成行
            ItTakesTwoResult itTakesTwoResult = itTakesTwo(time);
            //随机美女
            WineShopBeauty wineShopBeauty = randomBeauty(itTakesTwoResult.getSpecialRegion());
            if (wineShopBeauty != null) {
                WineShopBeautyArray array = new WineShopBeautyArray();
                array.setArrayId(itTakesTwoResult.getArrayId());
                array.setGenerateTime(time);
                array.addWineShopBeauty(wineShopBeauty);
                array.setTakeItTwo(itTakesTwoResult.isTakesTwo());
                //需要排队
                if ((userWineShopData.getWaitWineShopBeautyArrays().size() > 0 || checkWineShopBeautyLimit(array)) && (!itTakesTwoResult.isTakesTwo() || !itTakesTwoResult.isLastRunning())) {
                    userWineShopData.addWaitWineShopBeautyArray(array);
                } else { //不用排队直接进酒肆
                    array.setEnterWineShopTime(time);
                    userWineShopData.addRunningBeautyArray(array);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 双人成行判断
     * @param time
     * @return
     */
    private ItTakesTwoResult itTakesTwo(long time) {
        ItTakesTwoResult itTakesTwoResult = new ItTakesTwoResult();
        //获取上一个生成的队列
        WineShopBeautyArray lastArray = getLastArray(itTakesTwoResult);
        //上一个队列不是空的 并且不是双人成行了 并且时间不超过双人成行配置时间 才满足双人成行条件
        if (lastArray != null && !lastArray.isTakeItTwo() && time - lastArray.getGenerateTime() <= GameConfig.WINESHOP_IT_TAKES_TWO_CD_TIME * DateHelper.SECOND_MILLIONS) {
            //获取双人成行会前往的餐饮区域列表
            Set<Integer> takesTwoRegionList = getTakesTwoRegionList();
            WineShopBeauty wineShopBeauty = lastArray.getWineShopBeautyList().get(0);
            //上一个列表的美女前往的首个餐饮区域 在双人成行会前往的餐饮区域列表之内
            if (wineShopBeauty != null && takesTwoRegionList.contains(wineShopBeauty.getRegionList().get(0))) {
                //概率命中 双人成行
                if (new RandomHelper().next(0, 1000) < GameConfig.WINESHOP_IT_TAKES_TWO_PRO) {
                    //双人成行 将上一个队列的队列id带给下一个
                    itTakesTwoResult.setArrayId(lastArray.getArrayId());
                    //首个前往的区域也带下去
                    itTakesTwoResult.setSpecialRegion(wineShopBeauty.getRegionList().get(0));
                    itTakesTwoResult.setTakesTwo(true);
                    //将上一个队列的双人成行状态改为true
                    lastArray.setTakeItTwo(true);
                    return itTakesTwoResult;
                }
            }
        }
        //没有双人成行则队列id+1
        userWineShopData.setMaxArrayId(userWineShopData.getMaxArrayId() + 1);
        itTakesTwoResult.setArrayId(userWineShopData.getMaxArrayId());
        return itTakesTwoResult;
    }

    /**
     * 获取上一个队列
     * @return
     * @param itTakesTwoResult
     */
    private WineShopBeautyArray getLastArray(ItTakesTwoResult itTakesTwoResult) {
        //有等待的队列 取最后一个
        List<WineShopBeautyArray> waitWineShopBeautyArrays = userWineShopData.getWaitWineShopBeautyArrays();
        if (waitWineShopBeautyArrays.size() > 0) {
            return waitWineShopBeautyArrays.get(waitWineShopBeautyArrays.size() - 1);
        } else {
            //有正在运行的队列 取最后一个
            List<WineShopBeautyArray> runningBeautyArrays = userWineShopData.getRunningBeautyArrays();
            if (runningBeautyArrays.size() > 0) {
                WineShopBeautyArray array = runningBeautyArrays.get(runningBeautyArrays.size() - 1);
                for (WineShopBeauty wineShopBeauty : array.getWineShopBeautyList()) {
                    if (wineShopBeauty.isExit()) {
                        return null;
                    }
                }
                //将正在运行的状态带回去
                itTakesTwoResult.setLastRunning(true);
                return array;
            }
        }
        return null;
    }

    /**
     * 获取双人成行可以前往的区域
     * @return
     */
    private Set<Integer> getTakesTwoRegionList() {
        Set<Integer> takesTwoRegionList = new HashSet<>();
        for (UserWineShopBuilding building : userWineShopBuildingMap.values()) {
            WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(building.getId());
            if (WineShopMgr.getItTakesTwoForwardRegions().contains(wineShopBuilding.getRegion())) {
                takesTwoRegionList.add(wineShopBuilding.getRegion());
            }
        }
        return takesTwoRegionList;
    }

    /**
     * 已经叫号的数量
     * @return
     */
    public long calcAlreadyCallCount() {
        return getCurReceptionBeautyNum() + userWineShopData.getReceptionBeautyCount();
    }

    /**
     * 一键叫号
     * @param respMsg
     * @param assistantFlag 是否是小玉助手
     * @return
     */
    public int oneKeyReceptionBeauty(WineShopProto.WineShopReceptionRespMsg.Builder respMsg, boolean assistantFlag) {
        //不满足一键招待开启条件
        if (calcAlreadyCallCount() < GameConfig.WINESHOP_ONE_KEY_RECEPTION_NEED) {
            return GameErrorCode.E_WINESHOP_ONEKEY_CONDITION_LIMIT;
        }

        int checkResult = receptionCheck(assistantFlag);
        if (checkResult != 0) {
            return checkResult;
        }
        //先算能招多少人
        int waitBeautyNum = calcWaitBeautyNum();
        //叫到上限还能加多少个 跟 体力 取小值
        long canReceptionNum = Math.min(getCanEnterWineShopBeautyCount() + GameConfig.WINESHOP_RECEPTION_LIMIT - waitBeautyNum - userWineShopData.getWaitGenerateCount(), userWineShopData.getPower());
        if (canReceptionNum == 0) {
            return GameErrorCode.E_WINESHOP_RECEPTION_NUM_LIMIT;
        }
        if (isWineShopEmpty()) {
            userWineShopData.setLastReceptionBeautyTime(System.currentTimeMillis());
        }
        int powerConsume = (int) canReceptionNum;
        //招多少扣多少
        userWineShopData.setWaitGenerateCount(userWineShopData.getWaitGenerateCount() + canReceptionNum);
        userWineShopData.setPower(userWineShopData.getPower() - powerConsume);
        //同步进程
        syncProcess();
        addActivityData(powerConsume);
        //小面任务进度
        player.getModule(XiaoMianModule.class).addWineShopCallNumber(powerConsume);
        player.notifyListener(eGamePlayerEventType.WineShopReception.getValue(),powerConsume);
        player.notifyListener(eGamePlayerEventType.UnionWineShopReception.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, powerConsume, player.getUserInfo().getUnionUid()));
        AutoLogMgr.add(new LogWineShopPower(getUserId(), userWineShopData.getPower(), false, powerConsume, eLogMoneyType.WineShopReceptionPowerConsume.getValue()));
        syncWineShopData();
        respMsg.setTimes(powerConsume);

        if (userWineShopData.getPower() <= 0) {
            //6.4.0小玉助手不触发现金礼包
            if (!assistantFlag) {
                player.notifyListener(eGamePlayerEventType.RechargeWineShopReceptionCountNew.getValue(), 0);
            }
        }
        try {
            travelRecoveryTime();
        }catch (Exception e){
            log.error("error:" + e);
        }
        return 0;
    }

    /**
     * 随机生成美女、门客
     */
    private WineShopBeauty randomBeauty(int specialRegion) {
        //可以生成的美女列表
        List<UserBeauty> canReceptionBeautyList = getCanReceptionBeautyList();
        //可以生成的门客列表
        List<UserPatrons> canReceptionPatronsList = getCanReceptionPatronsList();
        int randomNum = new RandomHelper().next(0, 1000);
        int generateBeautyWeight = GameConfig.WINESHOP_GENERATE_BEAUTY_WEIGHT;
        boolean isBeauty;
        //美女列表不是空的 并且 (概率命中 或者 门客列表是空的) 则生成美女
        if (canReceptionBeautyList.size() > 0 && (randomNum < generateBeautyWeight || canReceptionPatronsList.size() <= 0)) {
            isBeauty = true;
            //否则门客列表不是空的就生成门客
        } else if (canReceptionPatronsList.size() > 0) {
            isBeauty = false;
        } else {
            //否则不允许生成
            return null;
        }
        //随机事件
        WineShopEvent wineShopEvent = randomEvent(specialRegion, isBeauty);
        //没有满足条件的事件 不允许生成
        if (wineShopEvent == null) {
            return null;
        }
        userWineShopData.setMaxBeautyId(userWineShopData.getMaxBeautyId() + 1);
        WineShopBeauty wineShopBeauty = new WineShopBeauty();
        wineShopBeauty.setId(userWineShopData.getMaxBeautyId());
        wineShopBeauty.setEventId(wineShopEvent.getId());
        RandomHelper randomHelper = new RandomHelper();
        //根据时间随机前往的区域
        wineShopBeauty.setRegionList(randomRegionArray(wineShopEvent, specialRegion, isBeauty));
        int randomIndex;
        if (isBeauty) {
            //随机一个美女出来 并将其剔除出池子
            randomIndex = randomHelper.next(canReceptionBeautyList.size());
            UserBeauty userBeauty = canReceptionBeautyList.get(randomIndex);
            wineShopBeauty.setBeautyId(userBeauty.getBeautyId());
            userWineShopData.addGenerateBeauty(userBeauty.getBeautyId());
        } else {
            //随机一个门客出来 并将其剔除出池子
            randomIndex = randomHelper.next(canReceptionPatronsList.size());
            UserPatrons userPatrons = canReceptionPatronsList.get(randomIndex);
            wineShopBeauty.setBeautyId(userPatrons.getPatronsId());
            userWineShopData.addGeneratedPatronsList(userPatrons.getPatronsId());
        }
//        logger.error(JSONObject.toJSONString(userWineShopData.getGeneratedBeautyList()));
        return wineShopBeauty;
    }

    /**
     * 计算等候区等待的美女数量
     * @return 数量
     */
    private int calcWaitBeautyNum() {
        int waitNum = 0;
        for (WineShopBeautyArray waitWineShopBeautyArray : userWineShopData.getWaitWineShopBeautyArrays()) {
            for (WineShopBeauty beauty : waitWineShopBeautyArray.getWineShopBeautyList()) {
                if (!beauty.isExit()) {
                    waitNum += 1;
                }
            }
        }
        return waitNum;
    }

    /**
     * 计算酒肆室内的美女数量
     * @return 数量
     */
    private int calcInnerBeautyNum() {
        int runningNum = 0;
        for (WineShopBeautyArray waitWineShopBeautyArray : userWineShopData.getRunningBeautyArrays()) {
            for (WineShopBeauty beauty : waitWineShopBeautyArray.getWineShopBeautyList()) {
                if (!beauty.isExit()) {
                    runningNum += 1;
                }
            }
        }
        return runningNum;
    }

    /**
     * 计算酒肆室内的美女容量上限
     * @return
     */
    private int calcInnerBeautyLimitCount() {
        int count = 0;
        for (UserWineShopBuilding building : userWineShopBuildingMap.values()) {
            WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(building.getId());
            if (wineShopBuilding != null && wineShopBuilding.getBigType() != eWineShopBuildingType.PublicRegion.getType()) {
                count += wineShopBuilding.getGuest();
            }
        }
        return count + GameConfig.WINESHOP_GUEST_NUM_PAR;
    }

    /**
     * 计算酒肆等候区的美女容量上限
     * @return
     */
    private int calcWaitBeautyLimitCount() {
        int count = 0;
        for (UserWineShopBuilding building : userWineShopBuildingMap.values()) {
            WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(building.getId());
            if (wineShopBuilding != null && wineShopBuilding.getBigType() == eWineShopBuildingType.PublicRegion.getType()) {
                count += wineShopBuilding.getGuest();
            }
        }
        return count;
    }

    /**
     * 计算酒肆的当前美女数量
     * @param isAddWait 是否加上等候区
     * @return  数量
     */
    private int calcWineShopBeautyCount(boolean isAddWait) {
        int count = calcInnerBeautyNum();
        if (isAddWait) {
            count += calcWaitBeautyNum();
        }
        return count;
    }

    /**
     * 计算能进入酒肆的美女数量
     * @return 数量
     */
    private int getCanEnterWineShopBeautyCount() {
        int maxCount = calcInnerBeautyLimitCount();
        int runningCount = calcWineShopBeautyCount(false);
        return maxCount - runningCount;
    }
    /**
     * 检查酒肆内是否已满员
     * @return bool
     * @param array 新增的队列
     */
    private boolean checkWineShopBeautyLimit(WineShopBeautyArray array) {
        int maxCount = calcInnerBeautyLimitCount();
        int count = calcWineShopBeautyCount(false);
        if (array == null) {
            return count >= maxCount;
        } else {
            return count + array.getWineShopBeautyList().size() > maxCount;
        }
    }

    /**
     * 随机建筑列表
     * @param event 事件
     * @param isBeauty
     * @return 建筑列表
     */
    private List<Integer> randomRegionArray(WineShopEvent event, int specialRegion, boolean isBeauty) {
        //玩家酒肆建筑列表
        Map<Integer, WineShopBuilding> unLockRegionBuildingMap = new ConcurrentHashMap<>();
        //已解锁的建筑列表筛选出区域列表
        for (UserWineShopBuilding building : userWineShopBuildingMap.values()) {
            WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(building.getId());
            if (wineShopBuilding != null) {
                if (!unLockRegionBuildingMap.containsKey(wineShopBuilding.getRegion())) {
                    unLockRegionBuildingMap.put(wineShopBuilding.getRegion(), wineShopBuilding);
                }
            }
        }
        //检查下座位 将已解锁的区域但没有座位的 筛选出去
        List<WineShopBuilding> randomBuildingList = unLockRegionBuildingMap.values().stream().filter(this::checkSeat).collect(Collectors.toList());
        //随机美女酒肆前往区域的列表
        List<WineShopBuilding> buildingArr = new ArrayList<>();
        //随机餐饮区域
        randomCatering(randomBuildingList, buildingArr, event.getCateringTimes());
        //随机娱乐区域
        randomEntertainment(randomBuildingList, buildingArr, event.getEntertainmentTimes(), isBeauty);
        List<Integer> regionArr = new ArrayList<>();
        //根据大类型排序 餐饮先去
        buildingArr.sort(Comparator.comparing(WineShopBuilding::getBigType));
        for (WineShopBuilding wineShopBuilding : buildingArr) {
            regionArr.add(wineShopBuilding.getRegion());
        }
        //先去娱乐的概率
        int reverseRandom;
        String[] split = GameConfig.WINESHOP_GUEST_TO_ENT_PRO.split("\\|");
        if (isBeauty) {
            reverseRandom = Integer.parseInt(split[0]);
        } else {
            reverseRandom = Integer.parseInt(split[1]);
        }
        //有指定首个餐饮区域的 将首个替换掉
        if (specialRegion != 0) {
            if (regionArr.stream().anyMatch(region -> region == specialRegion)) {
                regionArr.remove((Integer) specialRegion);
                regionArr.add(0, specialRegion);
            } else {
                regionArr.set(0, specialRegion);
            }
            //没有指定的则不是双人成行 判断一下概率 -> 先让顾客先去娱乐再餐饮
        } else if (event.getEntertainmentTimes() > 0 && new RandomHelper().next(1000) < reverseRandom) {
            Collections.reverse(regionArr);
        }
        return regionArr;
    }

    /**
     * 随机娱乐区域
     *
     * @param randomBuildingList
     * @param buildingArr
     * @param entertainmentTimes
     * @param isBeauty
     */
    private void randomEntertainment(List<WineShopBuilding> randomBuildingList, List<WineShopBuilding> buildingArr, int entertainmentTimes, boolean isBeauty) {
        //筛选玩家娱乐区域列表
        List<WineShopBuilding> entertainmentBuildings = randomBuildingList.stream().filter(wineShopBuilding -> wineShopBuilding.getBigType() == eWineShopBuildingType.Entertainment.getType()).collect(Collectors.toList());
        if (isBeauty) {
            //美女根据配置权重随机娱乐区域
            Map<Integer, Integer> map = parseSecondFloorMap();
            List<Integer> needRemoveKey = new ArrayList<>();
            map.keySet().forEach(region -> {
                if (entertainmentBuildings.stream().noneMatch(wineShopBuilding -> wineShopBuilding.getRegion() == region)) {
                    needRemoveKey.add(region);
                }
            });
            for (Integer key : needRemoveKey) {
                map.remove(key);
            }
            List<Integer> randomRegionList = new ArrayList<>();
            for (int i = 0; i < entertainmentTimes; i++) {
                int randomKey = RandomHelper.getRandomKeyByWeight(map);
                randomRegionList.add(randomKey);
                map.remove(randomKey);
            }
            for (Integer randomRegion : randomRegionList) {
                for (WineShopBuilding wineShopBuilding : randomBuildingList) {
                    if (wineShopBuilding.getRegion() == randomRegion) {
                        buildingArr.add(wineShopBuilding);
                    }
                }
            }
        } else {
            //筛选玩家娱乐区域列表
            List<WineShopBuilding> wineShopBuildings = entertainmentBuildings.stream().filter(wineShopBuilding -> StringUtils.stringToIntegerList(GameConfig.WINESHOP_PATRONS_CAN_FORWARD_ENTERTAINMENT_REGION, ";").contains(wineShopBuilding.getRegion())).collect(Collectors.toList());
            RandomHelper randomHelper = new RandomHelper();
            for (int i = 0; i < entertainmentTimes; i++) {
                WineShopBuilding wineShopBuilding = wineShopBuildings.get(randomHelper.next(wineShopBuildings.size()));
                buildingArr.add(wineShopBuilding);
                wineShopBuildings.remove(wineShopBuilding);
            }
        }
    }

    /**
     * 解析美女娱乐区域权重配置
     * @return
     */
    private Map<Integer, Integer> parseSecondFloorMap() {
        Map<Integer, Integer> map = new HashMap<>();
        String[] split = GameConfig.WINESHOP_GUEST_BEAUTY_TO_SECOND_FLOOR.split("\\|");
        for (String str : split) {
            String[] split1 = str.split(";");
            map.put(Integer.parseInt(split1[0].trim()), Integer.parseInt(split1[1].trim()));
        }
        return map;
    }

    /**
     * 随机餐饮
     *
     * @param randomBuildingList
     * @param buildingArr
     * @param cateringTimes
     */
    private void randomCatering(List<WineShopBuilding> randomBuildingList, List<WineShopBuilding> buildingArr, int cateringTimes) {
        //筛选玩家餐饮区域列表
        List<WineShopBuilding> cateringBuildings = randomBuildingList.stream().filter(wineShopBuilding -> wineShopBuilding.getBigType() == eWineShopBuildingType.Catering.getType()).collect(Collectors.toList());
        //随机cateringTimes个餐饮区域
        for (int i = 0; i < cateringTimes; i++) {
            WineShopBuilding wineShopBuilding = cateringBuildings.get(new RandomHelper().next(cateringBuildings.size()));
            buildingArr.add(wineShopBuilding);
            cateringBuildings.remove(wineShopBuilding);
        }
    }

    /**
     * 检查区域是否有座位
     * @param wineShopBuilding
     * @return
     */
    private boolean checkSeat(WineShopBuilding wineShopBuilding) {
        int guestCount = 0;
        for (UserWineShopBuilding shopBuilding : userWineShopBuildingMap.values()) {
            WineShopBuilding building = WineShopMgr.getWineShopBuilding(shopBuilding.getId());
            if (building != null) {
                //同个区域的座位加起来
                if (wineShopBuilding.getRegion() == building.getRegion()) {
                    guestCount += building.getGuest();
                }
            }
        }
        return guestCount > 0;

    }

    /**
     * 获取随机事件
     * @param specialRegion
     * @param isBeauty
     * @return
     */
    private List<WineShopEvent> getCanRandomEventList(int specialRegion, boolean isBeauty) {
        Map<Integer, WineShopBuilding> regionBuildingMap = new HashMap<>();
        for (UserWineShopBuilding building : userWineShopBuildingMap.values()) {
            WineShopBuilding wineShopBuilding = WineShopMgr.getWineShopBuilding(building.getId());
            if (wineShopBuilding != null && !regionBuildingMap.containsKey(wineShopBuilding.getRegion())) {
                //如果是门客 还要判断一下解锁的娱乐区域是不是门客能够前往的
                if (isBeauty || (wineShopBuilding.getBigType() == eWineShopBuildingType.Catering.getType() || StringUtils.stringToIntegerList(GameConfig.WINESHOP_PATRONS_CAN_FORWARD_ENTERTAINMENT_REGION, ";").contains(wineShopBuilding.getRegion()))) {
                    //要判断一下该区域是不是有座位
                    if (checkSeat(wineShopBuilding)) {
                        regionBuildingMap.put(wineShopBuilding.getRegion(), wineShopBuilding);
                    }
                }
            }
        }
        int cateringBuilding = 0;
        int entertainmentBuilding = 0;
        List<WineShopEvent> wineShopEventList = new ArrayList<>();
        for (WineShopBuilding wineShopBuilding : regionBuildingMap.values()) {
            if (wineShopBuilding != null) {
                if (wineShopBuilding.getBigType() == eWineShopBuildingType.Catering.getType()) {
                    cateringBuilding++;
                } else if (wineShopBuilding.getBigType() == eWineShopBuildingType.Entertainment.getType()) {
                    entertainmentBuilding++;
                }
            }
        }
        for (WineShopEvent event : WineShopMgr.getWineShopEventMap().values()) {
            if (event.getCateringTimes() <= cateringBuilding && event.getEntertainmentTimes() <= entertainmentBuilding) {
                if (specialRegion == 0 || (specialRegion > 0 && event.getCateringTimes() > 0)) {
                    wineShopEventList.add(event);
                }
            }
        }
        return wineShopEventList;
    }

    /**
     * 随机事件
     *
     * @return 事件
     */
    private WineShopEvent randomEvent(int specialRegion, boolean isBeauty) {
        //获取可以随机的事件列表
        List<WineShopEvent> canRandomEventList = getCanRandomEventList(specialRegion, isBeauty);
        if (canRandomEventList.size() <= 0) {
            log.error("canRandomEventList size is 0, playerId:{}", player.getUserId());
            return null;
        }
        //根据事件权重随机事件
        List<Integer> weightList = canRandomEventList.stream().map(WineShopEvent::getWeight).collect(Collectors.toList());
        int randomIndex = RandomHelper.getRandomIndexByWeight(weightList);
        return canRandomEventList.get(randomIndex);
    }

    /**
     * 可以生成的美女列表
     * @return 美女列表
     */
    private List<UserBeauty> getCanReceptionBeautyList() {
        // 美女列表
        Map<Integer, UserBeauty> userBeautyMap = player.getModule(BeautyModule.class).getBeautyMap();
        List<UserBeauty> canReceptionList = new ArrayList<>();
        for(UserBeauty beauty : userBeautyMap.values()) {
            // 织布中的美女排除
            if (!player.getModule(ColdRoomModule.class).isBeautyFree(beauty.getBeautyId())) {
                continue;
            }
            canReceptionList.add(beauty);
        }
        //检查一下美女池子是否要重置
        checkBeautyGeneratedPool(canReceptionList);
        List<UserBeauty> checkResultList = new ArrayList<>();
        for (UserBeauty beauty : canReceptionList) {
            boolean remove = false;
            // 酒肆内的美女排除
            for (WineShopBeautyArray runningBeautyArray : userWineShopData.getRunningBeautyArrays()) {
                for (WineShopBeauty wineShopBeauty : runningBeautyArray.getWineShopBeautyList()) {
                    if (wineShopBeauty.getBeautyId() == beauty.getBeautyId() && !wineShopBeauty.isExit()) {
                        remove = true;
                        break;
                    }
                }
            }
            if (remove) {
                continue;
            }
            // 排队列表里的美女排除
            for (WineShopBeautyArray waitWineShopBeautyArray : userWineShopData.getWaitWineShopBeautyArrays()) {
                for (WineShopBeauty wineShopBeauty : waitWineShopBeautyArray.getWineShopBeautyList()) {
                    if (wineShopBeauty.getBeautyId() == beauty.getBeautyId()) {
                        remove = true;
                        break;
                    }
                }
            }
            if (remove) {
                continue;
            }
            checkResultList.add(beauty);
        }
        return checkResultList;
    }

    /**
     * 可以生成的门客列表
     * @return 门客列表
     */
    private List<UserPatrons> getCanReceptionPatronsList() {
        List<UserPatrons> canReceptionList = player.getModule(PatronsModule.class).getUserPatronsList();
        checkPatronsGeneratedPool(canReceptionList);
        List<UserPatrons> checkResultList = new ArrayList<>();
        for (UserPatrons patrons : canReceptionList) {
            boolean remove = false;
            // 酒肆内的门客排除
            for (WineShopBeautyArray runningBeautyArray : userWineShopData.getRunningBeautyArrays()) {
                for (WineShopBeauty wineShopBeauty : runningBeautyArray.getWineShopBeautyList()) {
                    if (wineShopBeauty.getBeautyId() == patrons.getPatronsId() && !wineShopBeauty.isExit()) {
                        remove = true;
                        break;
                    }
                }
            }
            if (remove) {
                continue;
            }
            // 排队列表里的门客排除
            for (WineShopBeautyArray waitWineShopBeautyArray : userWineShopData.getWaitWineShopBeautyArrays()) {
                for (WineShopBeauty wineShopBeauty : waitWineShopBeautyArray.getWineShopBeautyList()) {
                    if (wineShopBeauty.getBeautyId() == patrons.getPatronsId()) {
                        remove = true;
                        break;
                    }
                }
            }
            if (remove) {
                continue;
            }
            checkResultList.add(patrons);
        }
        return checkResultList;
    }

    /**
     * 检测已生成的美女池子是否要刷新
     * @param canReceptionList
     */
    private void checkBeautyGeneratedPool(List<UserBeauty> canReceptionList) {
        for (Integer beautyId : userWineShopData.getGeneratedBeautyList()) {
            for (UserBeauty userBeauty : canReceptionList) {
                if (userBeauty.getBeautyId() == beautyId) {
                    canReceptionList.remove(userBeauty);
                    break;
                }
            }
        }
        if (canReceptionList.size() == 0) {
            userWineShopData.setGeneratedBeautyList(new ArrayList<>());
            Map<Integer, UserBeauty> userBeautyMap = player.getModule(BeautyModule.class).getBeautyMap();
            for(UserBeauty beauty : userBeautyMap.values()) {
                // 织布中的美女排除
                if (!player.getModule(ColdRoomModule.class).isBeautyFree(beauty.getBeautyId())) {
                    continue;
                }
                canReceptionList.add(beauty);
            }
        }
    }

    /**
     * 检测已生成的门客池子是否要刷新
     * @param canReceptionList
     */
    private void checkPatronsGeneratedPool(List<UserPatrons> canReceptionList) {
        for (Integer patronsId : userWineShopData.getGeneratedPatronsList()) {
            for (UserPatrons userPatrons : canReceptionList) {
                if (userPatrons.getPatronsId() == patronsId) {
                    canReceptionList.remove(userPatrons);
                    break;
                }
            }
        }
        if (canReceptionList.size() == 0) {
            userWineShopData.setGeneratedPatronsList(new ArrayList<>());
            Map<Integer, UserPatrons> userPatronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
            canReceptionList.addAll(userPatronsMap.values());
        }
    }

    /**
     * 美女结算并离开
     * @param id 美女唯一id
     * @return ret
     */
    public int beautyPayAndExit(long id) {
        for (WineShopBeautyArray runningBeautyArray : userWineShopData.getRunningBeautyArrays()) {
            for (WineShopBeauty wineShopBeauty : runningBeautyArray.getWineShopBeautyList()) {
                if (wineShopBeauty.getId() == id) {
                    if (wineShopBeauty.isExit()) {
                        return GameErrorCode.E_WINESHOP_BEAUTY_GUEST_NO_FOUND;
                    }
                    if (System.currentTimeMillis() - runningBeautyArray.getGenerateTime() < 10 * DateHelper.SECOND_MILLIONS) {
                        return GameErrorCode.E_WINESHOP_RECEPTION_IS_FAST;
                    }
                    //美女离开
                    if (beautyPayAndExit(wineShopBeauty, runningBeautyArray)) {
                        userWineShopData.getRunningBeautyArrays().remove(runningBeautyArray);
                    }
                    //下一个美女队列进入酒肆
                    syncProcess();
                    syncWineShopData();
                    return 0;
                }
            }
        }
        return GameErrorCode.E_WINESHOP_BEAUTY_GUEST_NO_FOUND;
    }

    /**
     * 美女结算并离开
     *
     * @param wineShopBeauty
     * @param beautyArray
     * @return
     */
    private boolean beautyPayAndExit(WineShopBeauty wineShopBeauty, WineShopBeautyArray beautyArray) {
        wineShopBeauty.setExit(true);
        //美女结算
        beautyPay(wineShopBeauty);
        userWineShopData.setLastReceptionBeautyTime(System.currentTimeMillis());
        return wineShopArrayRemove(beautyArray);
    }

    /**
     * 队列内的美女都离开则移除队列
     * @param beautyArray
     * @return
     */
    private boolean wineShopArrayRemove(WineShopBeautyArray beautyArray) {
        boolean remove = true;
        for (WineShopBeauty wineShopBeauty : beautyArray.getWineShopBeautyList()) {
            if (!wineShopBeauty.isExit()) {
                remove = false;
            }
        }
        return remove;
    }

    /**
     * 需要同步进程
     * @return
     */
    private boolean needSyncProcess() {
        //酒肆还没满 或者等候区没满 或者有等待生成的顾客
        return (calcInnerBeautyNum() < calcInnerBeautyLimitCount() || calcWaitBeautyNum() < calcWaitBeautyLimitCount()) || userWineShopData.getWaitGenerateCount() > 0;
    }

    /**
     * 同步进程
     */
    private void syncProcess() {
        //是否重复进程
        boolean isRepeated = true;
        while (needSyncProcess() && isRepeated) {
            //同步等待队列进入酒肆
            syncWaitEnterWineShop();
            //同步生成队列 有新生成的需要重复进程
            isRepeated = syncGenerateBeauty();
        }
    }
    /**
     * 同步等候区进入酒肆
     */
    private void syncWaitEnterWineShop() {
        long nowTime = System.currentTimeMillis();
        //酒肆还没满(满了就不给进)
        int whileTimes = 0;
        int maxWhileTimes = calcInnerBeautyLimitCount() - calcInnerBeautyNum();
        while (calcInnerBeautyNum() < calcInnerBeautyLimitCount()) {
            whileTimes++;
            //还有队列在排队等候(没人就跳出)
            if (userWineShopData.getWaitWineShopBeautyArrays().size() > 0) {
                //取队列第一个
                WineShopBeautyArray array = userWineShopData.getWaitWineShopBeautyArrays().get(0);
                array.setEnterWineShopTime(nowTime);
                userWineShopData.addRunningBeautyArray(array);
                userWineShopData.getWaitWineShopBeautyArrays().remove(array);
                //判断是不是和第二个人双人成行 是的话一起走 （双人成行即使满了也可以一起走）
                if (array.isTakeItTwo() && userWineShopData.getWaitWineShopBeautyArrays().size() > 0) {
                    WineShopBeautyArray secondArray = userWineShopData.getWaitWineShopBeautyArrays().get(0);
                    if (secondArray.isTakeItTwo() && secondArray.getArrayId() == array.getArrayId()) {
                        secondArray.setEnterWineShopTime(nowTime);
                        userWineShopData.addRunningBeautyArray(secondArray);
                        userWineShopData.getWaitWineShopBeautyArrays().remove(secondArray);
                    }
                }
            } else {
                break;
            }
            if (whileTimes > maxWhileTimes) {
                break;
            }
        }
    }

    /**
     * 同步生成美女进程
     */
    private boolean syncGenerateBeauty() {
        long nowTime = System.currentTimeMillis();
        boolean hasNew = false;
        //等候区没满且还有等待生成的顾客
        int whileTimes = 0;
        while (calcWaitBeautyNum() < calcWaitBeautyLimitCount() && userWineShopData.getWaitGenerateCount() > 0) {
            whileTimes ++;
            //生成美女
            if (generateBeauty(nowTime)) {
                hasNew = true;
                userWineShopData.setWaitGenerateCount(userWineShopData.getWaitGenerateCount() - 1);
            } else {
                break;
            }
            if (whileTimes > userWineShopData.getWaitGenerateCount()) {
                break;
            }
        }
        return hasNew;
    }

    public long calcMoneyReward(Map<Integer, UserWineShopBuilding> buildingMap, GamePlayer player) {
        long moneyReward = WineShopMgr.calcMoneyReward(buildingMap);
        //藏品加成
        long addition = CurioMgr.getSkillAdditionBySkillType(eSkillType.WineShopMoneySkill.getValue(), player, 0);
        moneyReward = BigDecimal.valueOf(moneyReward).multiply(BigDecimal.valueOf(1000 + addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).longValue();
        return moneyReward;
    }

    /**
     * 美女结算
     * @param wineShopBeauty 美女
     */
    private void beautyPay(WineShopBeauty wineShopBeauty) {
        //银条奖励
        long moneyReward = calcMoneyReward(userWineShopBuildingMap, player);
        long expReward;
        WineShopReward yieldReward = userWineShopData.getYieldReward();
        if (!yieldReward.getBeautyRewardMap().containsKey(wineShopBeauty.getBeautyId())) {
            WineShopBeautyReward reward = new WineShopBeautyReward();
            reward.setBeautyId(wineShopBeauty.getBeautyId());
            yieldReward.getBeautyRewardMap().put(wineShopBeauty.getBeautyId(), reward);
        }
        if (WineShopMgr.isBeauty(wineShopBeauty.getBeautyId())) {
            //经验奖励
            expReward = WineShopMgr.calcExp(userWineShopData.getWineShopLv(), eSkillType.WineShopBeautyEscortExpAdd.getValue());
            //结算人数+1
            yieldReward.setBeautyCount(yieldReward.getBeautyCount() + 1);
        } else {
            expReward = WineShopMgr.calcExp(userWineShopData.getWineShopLv(), eSkillType.WineShopPatronsBaiYeExpAdd.getValue());
            yieldReward.setPatronsCount(yieldReward.getPatronsCount() + 1);
        }
        WineShopBeautyReward reward = yieldReward.getBeautyRewardMap().get(wineShopBeauty.getBeautyId());
        reward.setMoneyValue(reward.getMoneyValue() + moneyReward);
        reward.setExpValue(reward.getExpValue() + expReward);

        //冲榜活动数据
        Map<Integer, WineShopRankActivityData> rankActivityDataMap = userWineShopData.getWineShopRankActivityDataMap();
        for (WineShopRankActivityData rankActivityData : rankActivityDataMap.values()) {
            ActivityInfo activityInfo = NormalActivityMgr.getActivityInfo(rankActivityData.getActivityId());
            if (rankActivityData.getNeedAddMoneyBeautyNum() >= getCurReceptionBeautyNum()
                    && ActivityMgr.activityInTime(activityInfo)) {
                //酒肆冲榜 是银条冲榜
                if (activityInfo.getChildType() == eRankActivityType.WineShopPleasureRiseRank.getValue() || activityInfo.getChildType() == eCrossRankActivityType.CrossWineShopPleasureRiseRank.getValue()) {
                    rankActivityData.setMoney(rankActivityData.getMoney() + moneyReward);
                    //还有才艺冲榜 是美女才艺经验冲榜
                } else if (activityInfo.getChildType() == eRankActivityType.BeautyEscortAddExpRank.getValue() || activityInfo.getChildType() == eCrossRankActivityType.CrossBeautyEscortAddExpRank.getValue()) {
                    if (WineShopMgr.isBeauty(wineShopBeauty.getBeautyId())) {
                        rankActivityData.setMoney(rankActivityData.getMoney() + expReward);
                    }
                }
            }
        }
        userWineShopData.setReceptionBeautyCount(userWineShopData.getReceptionBeautyCount() + 1);
        userWineShopData.setUpdateOption();
    }

    private long getCurReceptionBeautyNum() {
        return userWineShopData.getWaitGenerateCount() + calcWineShopBeautyCount(true);
    }

    /**
     * 招待检查
     * @return ret
     */
    private int receptionCheck(boolean assistantFlag) {
        //检查解锁
        if (!checkUnLock()) {
            return GameErrorCode.E_WINESHOP_BUILDING_IS_LOCK;
        }
        recoveryEnergy();
        if (userWineShopData.getPower() <= 0) {
            //触发现金礼包,6.4.0小玉助手不触发现金礼包
            if (!assistantFlag) {
                player.notifyListener(eGamePlayerEventType.RechargeWineShopReceptionCount.getValue(), 0);
                player.notifyListener(eGamePlayerEventType.RechargeWineShopReceptionCountNew.getValue(), 0);
            }
            return GameErrorCode.E_WINESHOP_POWER_LIMIT;
        }
        return 0;
    }

    /**
     * 是否解锁
     * @return bool
     */
    private boolean checkUnLock() {
        return userWineShopBuildingMap.size() > 0;
    }

    /**
     * 获取酒肆收益
     * @param respMsg 返回
     */
    public void getWineShopReward(WineShopProto.WineShopGetRewardRespMsg.Builder respMsg) {
        long nowTime = System.currentTimeMillis();
        WineShopReward yieldReward = userWineShopData.getYieldReward();
        if (yieldReward.getBeautyRewardMap().size() == 0) {
            respMsg.setRet(GameErrorCode.E_WINESHOP_REWARD_IS_EMPTY);
            return;
        }
        //奖励拿出后 清空奖励
        clearWineShopReward();
        respMsg.setGetRewardTime(userWineShopData.getGetRewardTime());
        userWineShopData.setGetRewardTime(nowTime);
        List<UserBeauty> syncBeautyList = new ArrayList<>();
        List<UserPatrons> syncPatronsList = new ArrayList<>();
        long moneyReward = 0;
        long logTime = System.currentTimeMillis();
        for (WineShopBeautyReward reward : yieldReward.getBeautyRewardMap().values()) {
            moneyReward += reward.getMoneyValue();
            if (WineShopMgr.isBeauty(reward.getBeautyId())) {
                UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(reward.getBeautyId());
                if (userBeauty != null) {
                    //美女加才艺经验
                    player.getModule(BeautyModule.class).addBeautyEscortExp(userBeauty, reward.getExpValue());
                    AutoLogMgr.add(new LogWineShopReward(getUserId(), eItemId.BEAUTY_ESCORT_EXP_GOODS.getValue(), reward.getExpValue(),
                            userBeauty.getEscortExp(), eLogMoneyType.WineShopGetRewardGet.getValue(), userBeauty.getBeautyId()));
                    AutoLogMgr.add(new LogBeautySkillExp(player.getUserId(), userBeauty.getBeautyId(), reward.getExpValue(), userBeauty.getEscortExp(), eLogMoneyType.WineShop.getValue(), eLogMoneyType.WineShopGetRewardGet.getValue()));
                    syncBeautyList.add(userBeauty);
                    WineShopRankArgs wineShopRankArgs = new WineShopRankArgs(userWineShopData.getWineShopRankActivityDataMap());
                    //才艺冲榜
                    player.notifyListener(eGamePlayerEventType.BeautyEscortAddExpRank.getValue(), wineShopRankArgs);
                }
            } else {
                UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(reward.getBeautyId());
                if (userPatrons != null) {
                    //门客加百业经验
                    userPatrons.setBaiYeExp(userPatrons.getBaiYeExp() + reward.getExpValue());
                    AutoLogMgr.add(new LogWineShopReward(getUserId(), GameConfig.PATRONS_BAIYE_EXP_ID, reward.getExpValue(),
                            userPatrons.getBaiYeExp(), eLogMoneyType.WineShopGetRewardGet.getValue(), userPatrons.getPatronsId()));
                }
                syncPatronsList.add(userPatrons);
            }
        }
        player.getModule(CurrencyModule.class).addCurrency(new Property(GameConfig.WINESHOP_MONEY_ITEM_ID, BigInteger.valueOf(moneyReward)), eLogMoneyType.WineShop, eLogMoneyType.WineShopGetRewardGet);
        WineShopRankArgs wineShopRankArgs = new WineShopRankArgs(userWineShopData.getWineShopRankActivityDataMap());
        //酒肆冲榜
        player.notifyListener(eGamePlayerEventType.WineShopPleasureRiseRank.getValue(), wineShopRankArgs);
        respMsg.setRet(0);
        respMsg.setReward(WineShopPb.parseReward(yieldReward));
        syncWineShopData();
        player.getModule(BeautyModule.class).syncUserBeauty(syncBeautyList, false);
        player.getModule(PatronsModule.class).syncPatronsData(syncPatronsList, false);
    }

    /**
     * 清理酒肆收益
     */
    private void clearWineShopReward() {
        WineShopReward yieldReward = new WineShopReward();
        yieldReward.setBeautyRewardMap(new ConcurrentHashMap<>());
        userWineShopData.setYieldReward(yieldReward);
    }

    /**
     * 酒肆改名
     * @param nickName 名称
     */
    public int changeNickName(String nickName) {
        //清前后空格
        nickName = StringUtils.clearHeadAndTailEmpty(nickName);
        int nameLength = StringUtils.getStringLen(nickName);
        //名字长度限制
        if (nameLength > WineShopMgr.WINESHOP_MAX_NICK_NAME_LENGTH || nameLength < WineShopMgr.WINESHOP_MIN_NICK_NAME_LENGTH) {
            return GameErrorCode.E_NAME_LENGTH_OVER;
        }
        //敏感词限制
        if (ForbiddenWordMgr.isNickNameForbidden(nickName)) {
            return GameErrorCode.E_FORBIDDEN_WORD;
        }
        if(userWineShopData.getChangeNickNameTimes() > 0){
            //编辑限制
            GameEditLimit gameEditLimit = GameEditLimitMgr.getGameEditLimit(Protocol.S_WINESHOP_CHANGE_NAME);
            if(null != gameEditLimit){
                long nowTime = System.currentTimeMillis();
                if(nowTime >= gameEditLimit.getLimitEditStartTime() && nowTime < gameEditLimit.getLimitEditEndTime()){
                    return GameErrorCode.E_SYSTEM_NO_OPEN;
                }
            }
        }
        //根据改名次数获取改名消耗
        BigInteger changeNickNameCost = WineShopMgr.getChangeNickNameCost(userWineShopData.getChangeNickNameTimes());
        if (!player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.GAME_MONEY_INGOTS, changeNickNameCost), eLogMoneyType.WineShop, eLogMoneyType.WineShopChangeNickNameConsume)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        userWineShopData.setWineShopName(nickName);
        userWineShopData.setChangeNickNameTimes(userWineShopData.getChangeNickNameTimes() + 1);
        //改完名同步一下知名榜
        changePopularityValueRank();
        syncWineShopData();
        return 0;
    }

    /**
     * 使用体力道具
     * @param count 数量
     * @return  ret
     */
    public int useWineShopPowerAddItem(int count) {
        if (count <= 0) {
            return GameErrorCode.E_USE_ITEM_NUM_ERROR;
        }
        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(GameConfig.WINESHOP_ADD_POWER_ITEM);
        if (goodsInfo == null) {
            return GameErrorCode.E_WINESHOP_ITEM_CONFIG_NO_FOUND;
        }
        if (!player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.WINESHOP_ADD_POWER_ITEM, BigInteger.valueOf(count)),
                eLogMoneyType.WineShop, eLogMoneyType.WineShopUsePowerAddItemConsume)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        //先同步一下体力
        recoveryEnergy();
        int powerGet = goodsInfo.getParamList().get(0).intValue() * count;
        userWineShopData.setPower(userWineShopData.getPower() + powerGet);
        AutoLogMgr.add(new LogWineShopPower(getUserId(), userWineShopData.getPower(), true, powerGet, eLogMoneyType.WineShopUsePowerItemGet.getValue()));
        syncWineShopData();
        return 0;
    }


    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (userWineShopData != null) {
            if (userWineShopData.isInsertOption()) {
                UserWineShopBusiness.addUserWineShopData(userWineShopData);
            } else if (userWineShopData.isUpdateOption()) {
                UserWineShopBusiness.updateUserWineShop(userWineShopData);
            }
        }
        if (!userWineShopBuildingMap.isEmpty()) {
            for (UserWineShopBuilding userWineShopBuilding : userWineShopBuildingMap.values()) {
                if (userWineShopBuilding.isInsertOption()) {
                    UserWineShopBusiness.addUserWineShopBuildingData(userWineShopBuilding);
                } else if (userWineShopBuilding.isUpdateOption()) {
                    UserWineShopBusiness.updateUserWineShopBuildingData(userWineShopBuilding);
                }
            }
        }
        return true;
    }

    /**
     * 随机名字
     * @return
     */
    public int randomName() {
        WineShopProto.WineShopRandomNameRespMsg.Builder respMsg = WineShopProto.WineShopRandomNameRespMsg.newBuilder();
        List<Integer> randomNameIndex = new ArrayList<>();
        String[] split = GameConfig.WINESHOP_NAME_NUM_CONFIG.split(";");
        for (String s : split) {
            int num = Integer.parseInt(s);
            randomNameIndex.add(new RandomHelper().next(1, num + 1));
        }
        respMsg.setRandomName(StringUtils.listToString(randomNameIndex, ";"));
        respMsg.setRet(0);
        player.sendPacket(ClientProtocol.U_WINESHOP_RANDOM_NAME, respMsg);
        return 0;
    }

    /**
     * 酒肆离线接待美女
     */
    public void offLineReception() {
        //离线接待结算完已生成美女所需的离线时间
        long payBeautyOffLineCostTime = GameConfig.WINESHOP_OFFLINE_SETTLEMENT_TIME * DateHelper.SECOND_MILLIONS;
        long nowTime = System.currentTimeMillis();
        //当前时间 - 上一次接待完成的时间 = 离线的时间
        long durTime = nowTime - userWineShopData.getLastReceptionBeautyTime();
        //离线时间不足以结算场上美女 不做离线操作 同步酒肆数据并返回
        if (durTime < payBeautyOffLineCostTime) {
            syncWineShopData();
            return;
        }
        //先结算掉场上已生成的美女
        List<WineShopBeautyArray> needRemoveList = new ArrayList<>();
        for (WineShopBeautyArray runningBeautyArray : userWineShopData.getRunningBeautyArrays()) {
            for (WineShopBeauty wineShopBeauty : runningBeautyArray.getWineShopBeautyList()) {
                if (!wineShopBeauty.isExit()) {
                    if (beautyPayAndExit(wineShopBeauty, runningBeautyArray)) {
                        needRemoveList.add(runningBeautyArray);
                    }
                }
            }
        }
        for (WineShopBeautyArray wineShopBeautyArray : needRemoveList) {
            userWineShopData.getRunningBeautyArrays().remove(wineShopBeautyArray);
        }
        List<WineShopBeautyArray> needRemoveList2 = new ArrayList<>();
        for (WineShopBeautyArray wineShopBeautyArray : userWineShopData.getWaitWineShopBeautyArrays()) {
            for (WineShopBeauty wineShopBeauty : wineShopBeautyArray.getWineShopBeautyList()) {
                if (!wineShopBeauty.isExit()) {
                    if (beautyPayAndExit(wineShopBeauty, wineShopBeautyArray)) {
                        needRemoveList2.add(wineShopBeautyArray);
                    }
                }
            }
        }
        for (WineShopBeautyArray wineShopBeautyArray : needRemoveList2) {
            userWineShopData.getWaitWineShopBeautyArrays().remove(wineShopBeautyArray);
        }
        userWineShopData.setLastReceptionBeautyTime(nowTime);
        //离线自动接待
        //离线自动接待时间长度应该去掉的时间 （一部分做头部结算 一部分做尾部生成）
        long calcOffLineReceptionNeedTime = GameConfig.WINESHOP_OFFLINE_REDUCE_TIME * DateHelper.SECOND_MILLIONS;
        if (durTime > calcOffLineReceptionNeedTime) {
            long calcTime = durTime - calcOffLineReceptionNeedTime;
            //计算需要自动接待的人数
            long needCalcNum = ClinicMgr.calcOffLineCureCount(userWineShopData.getWaitGenerateCount(), calcTime / DateHelper.SECOND_MILLIONS, GameConfig.WINESHOP_BEAUTY_OFFLINE_CALC_TIME_ONCE);
            long realCalcNum = 0;
            for (int i = 0; i < needCalcNum; i++) {
                WineShopBeauty wineShopBeauty = randomBeauty(0);
                if (wineShopBeauty == null) {
                    logger.error("random beauty is null, playerId:{}", getUserId());
                    break;
                }
                beautyPay(wineShopBeauty);
                userWineShopData.setWaitGenerateCount(userWineShopData.getWaitGenerateCount() - 1);
                realCalcNum++;
            }
            if (realCalcNum < needCalcNum) {
                userWineShopData.setLastReceptionBeautyTime(nowTime);
            } else if (realCalcNum > 0){
                userWineShopData.setLastReceptionBeautyTime(userWineShopData.getLastReceptionBeautyTime() + payBeautyOffLineCostTime + ClinicMgr.calcOffLineCureCostTime(userWineShopData.getWaitGenerateCount(), realCalcNum, GameConfig.WINESHOP_BEAUTY_OFFLINE_CALC_TIME_ONCE) * DateHelper.SECOND_MILLIONS);
            }
        }

        //离线生成美女
        if (userWineShopData.getWaitGenerateCount() > 0) {
            long generateTime = GameConfig.WINESHOP_OFFLINE_GENERATE_ALL_TIME * DateHelper.SECOND_MILLIONS;
            long generateSingleCostTime = GameConfig.WINESHOP_OFFLINE_GENERATE_PERIOD_TIME * DateHelper.SECOND_MILLIONS;
            long realGenerateNum = Math.min(Math.min(durTime - payBeautyOffLineCostTime, generateTime) / generateSingleCostTime, userWineShopData.getWaitGenerateCount());
            for (int i = 0; i < realGenerateNum; i++) {
                long time = System.currentTimeMillis() - generateTime + generateSingleCostTime * (i + 1);
                if (generateBeauty(time)) {
                    userWineShopData.setWaitGenerateCount(userWineShopData.getWaitGenerateCount() - 1);
                } else {
                    break;
                }
            }
            syncProcess();
        }
        syncWineShopData();
    }

    private void addActivityData(int num) {
        List<Integer> activityIdList = NormalActivityMgr.getOpenWineShopRankActivityIdList();
        Map<Integer, WineShopRankActivityData> rankActivityDataMap = userWineShopData.getWineShopRankActivityDataMap();
        synchronized (rankActivityDataMap) {
            for (Integer activityId : activityIdList) {
                if (!ActivityMgr.activityInTime(NormalActivityMgr.getActivityInfo(activityId))) {
                    continue;
                }
                if (!rankActivityDataMap.containsKey(activityId)) {
                    WineShopRankActivityData data = new WineShopRankActivityData();
                    data.setActivityId(activityId);
                    data.setNeedAddMoneyBeautyNum(0);
                    rankActivityDataMap.put(activityId, data);
                }
                WineShopRankActivityData data = rankActivityDataMap.get(activityId);
                data.setNeedAddMoneyBeautyNum(data.getNeedAddMoneyBeautyNum() + num);
                userWineShopData.setUpdateOption();
            }
        }
    }

    /**
     * v5.6奖励找回 只找回奖励
     */

    public WineShopProto.WineShopGetRewardRespMsg.Builder recoverReward(int times) {

        WineShopProto.WineShopGetRewardRespMsg.Builder respMsg = WineShopProto.WineShopGetRewardRespMsg.newBuilder();
        //银条奖励
        long moneyReward = calcMoneyReward(userWineShopBuildingMap, player);
        long expReward;

        WineShopReward yieldReward = new WineShopReward();
        yieldReward.setBeautyRewardMap(new ConcurrentHashMap<>());

        //结果
        List<Integer> beautyPatronIdList = new ArrayList<>();
        //随机镁铝或者门客,之前的方法用不了
        for (int i = 0; i < times; i++) {
            int randomNum = new RandomHelper().next(0, 1000);
            int generateBeautyWeight = GameConfig.WINESHOP_GENERATE_BEAUTY_WEIGHT;
            int resultId = 0;
            if (randomNum < generateBeautyWeight) {
                resultId = player.getModule(BeautyModule.class).getRandomBeauty().getBeautyId();

            } else {
                resultId = player.getModule(PatronsModule.class).getRandomPatrons(0).getPatronsId();
            }
            if (resultId != 0) {
                beautyPatronIdList.add(resultId);
            }
        }
        //先一个个结算奖励 放到暂存里面
        for (Integer wineShopBeauty : beautyPatronIdList) {
            if (!yieldReward.getBeautyRewardMap().containsKey(wineShopBeauty)) {
                WineShopBeautyReward reward = new WineShopBeautyReward();
                reward.setBeautyId(wineShopBeauty);
                yieldReward.getBeautyRewardMap().put(wineShopBeauty, reward);
            }
            if (WineShopMgr.isBeauty(wineShopBeauty)) {
                //经验奖励
                expReward = WineShopMgr.calcExp(userWineShopData.getWineShopLv(), eSkillType.WineShopBeautyEscortExpAdd.getValue());
                //结算人数+1
                yieldReward.setBeautyCount(yieldReward.getBeautyCount() + 1);
            } else {
                expReward = WineShopMgr.calcExp(userWineShopData.getWineShopLv(), eSkillType.WineShopPatronsBaiYeExpAdd.getValue());
                yieldReward.setPatronsCount(yieldReward.getPatronsCount() + 1);
            }

            WineShopBeautyReward reward = yieldReward.getBeautyRewardMap().get(wineShopBeauty);
            reward.setMoneyValue(reward.getMoneyValue() + moneyReward);
            reward.setExpValue(reward.getExpValue() + expReward);
            userWineShopData.setReceptionBeautyCount(userWineShopData.getReceptionBeautyCount() + 1);
            userWineShopData.setUpdateOption();
        }
        //领取暂存收益

        List<UserBeauty> syncBeautyList = new ArrayList<>();
        List<UserPatrons> syncPatronsList = new ArrayList<>();
        long totalMoneyReward = 0;
        long logTime = System.currentTimeMillis();
        for (WineShopBeautyReward reward : yieldReward.getBeautyRewardMap().values()) {
            totalMoneyReward += reward.getMoneyValue();
            if (WineShopMgr.isBeauty(reward.getBeautyId())) {
                UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(reward.getBeautyId());
                if (userBeauty != null) {
                    //美女加才艺经验
                    player.getModule(BeautyModule.class).addBeautyEscortExp(userBeauty, reward.getExpValue());
                    AutoLogMgr.add(new LogWineShopReward(getUserId(), eItemId.BEAUTY_ESCORT_EXP_GOODS.getValue(), reward.getExpValue(),
                            userBeauty.getEscortExp(), eLogMoneyType.WineShopGetRewardGet.getValue(), userBeauty.getBeautyId()));
                    AutoLogMgr.add(new LogBeautySkillExp(player.getUserId(), userBeauty.getBeautyId(), reward.getExpValue(), userBeauty.getEscortExp(), eLogMoneyType.WineShop.getValue(), eLogMoneyType.WineShopGetRewardGet.getValue()));
                    syncBeautyList.add(userBeauty);

                }
            } else {
                UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(reward.getBeautyId());
                if (userPatrons != null) {
                    //门客加百业经验
                    userPatrons.setBaiYeExp(userPatrons.getBaiYeExp() + reward.getExpValue());
                    AutoLogMgr.add(new LogWineShopReward(getUserId(), GameConfig.PATRONS_BAIYE_EXP_ID, reward.getExpValue(),
                            userPatrons.getBaiYeExp(), eLogMoneyType.WineShopGetRewardGet.getValue(), userPatrons.getPatronsId()));
                }
                syncPatronsList.add(userPatrons);
            }
        }
        player.getModule(CurrencyModule.class).addCurrency(new Property(GameConfig.WINESHOP_MONEY_ITEM_ID, BigInteger.valueOf(totalMoneyReward)), eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryWineShopReward);
        respMsg.setRet(0);
        respMsg.setReward(WineShopPb.parseReward(yieldReward));
        syncWineShopData();
        player.getModule(BeautyModule.class).syncUserBeauty(syncBeautyList, false);
        player.getModule(PatronsModule.class).syncPatronsData(syncPatronsList, false);
        return respMsg;
    }

    public int getLastSaveTimePower() {
        return lastSaveTimePower;
    }
}
